﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ManagedAPI;

namespace UnitTest
{
	/// <summary>
	/// Summary description for LexerTest
	/// </summary>
	[TestClass]
	public class LexerTest
	{
		public LexerTest()
		{

		}

		private TestContext testContextInstance;

		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext
		{
			get
			{
				return testContextInstance;
			}
			set
			{
				testContextInstance = value;
			}
		}

		#region Additional test attributes
		//
		// You can use the following additional attributes as you write your tests:
		//
		// Use ClassInitialize to run code before running the first test in the class
		// [ClassInitialize()]
		// public static void MyClassInitialize(TestContext testContext) { }
		//
		// Use ClassCleanup to run code after all tests in a class have run
		// [ClassCleanup()]
		// public static void MyClassCleanup() { }

		private static bool mOpenResult;
		// Use TestInitialize to run code before running each test 
		[TestInitialize()]
		public void MyTestInitialize()
		{
			mOpenResult = Database.Open(UnderstandGlobalData.GetFileName());
			Assert.IsTrue(mOpenResult);
		}
		//
		// Use TestCleanup to run code after each test has run
		[TestCleanup()]
		public void MyTestCleanup()
		{
			Database.Close();
			mOpenResult = false;
		}
		#endregion

		[TestMethod]
		public void Lexer_Test()
		{
			FileEntity fileEnt = Database.LookupFileEntity("foo_Util.h");

			Lexer lex = fileEnt.GetLexer();
			Assert.AreEqual(104, lex.Lines);

			Lexeme lexme = lex.First;
			Assert.AreEqual("#", lexme.Text);
			Assert.AreEqual(1, lexme.LineBegin);
			Assert.AreEqual(1, lexme.LineEnd);
			Assert.AreEqual(0, lexme.ColumnBegin);
			Assert.AreEqual(0, lexme.ColumnEnd);
			Assert.IsTrue(lexme.Active);
			Assert.AreEqual(UdbToken.Udb_tokenPreprocessor, lexme.Token);
		}
		[TestMethod]
		public void Lexer_Test_GetLexeme()
		{
			FileEntity fileEnt = Database.LookupFileEntity("foo_Util.h");
			MethodType[] funcs = fileEnt.GetFunctionDeclarations();
			MethodType funcBigWide = funcs[2];
			Reference refDef = funcBigWide.GetRef();

			Lexer lex = fileEnt.GetLexer();
			Lexeme lexme = lex.GetLexeme(refDef.Line, refDef.Column);
			Assert.AreEqual("BigAndWideMethod", lexme.Text);
			Assert.AreEqual(UdbToken.Udb_tokenIdentifier, lexme.Token);
		}
		[TestMethod]
		public void Lexer_Test_Previous()
		{
			FileEntity fileEnt = Database.LookupFileEntity("foo_Util.h");
			MethodType[] funcs = fileEnt.GetFunctionDeclarations();
			MethodType funcBigWide = funcs[2];
			Reference refDef = funcBigWide.GetRef();

			Lexer lex = fileEnt.GetLexer();
			Lexeme lexme = lex.GetLexeme(refDef.Line, refDef.Column);
			Assert.AreEqual("BigAndWideMethod", lexme.Text);

			Lexeme lexprev = lexme.Previous;
			Assert.AreEqual("\t\t", lexprev.Text);
			Assert.AreEqual(UdbToken.Udb_tokenWhitespace, lexprev.Token);

			lexprev = lexprev.Previous;
			Assert.AreEqual("\n", lexprev.Text);
			Assert.AreEqual(UdbToken.Udb_tokenNewline, lexprev.Token);

			lexprev = lexprev.Previous;
			Assert.AreEqual("void", lexprev.Text);
			Assert.AreEqual(UdbToken.Udb_tokenKeyword, lexprev.Token);
		}
		[TestMethod]
		public void Lexer_Test_Next()
		{
			FileEntity fileEnt = Database.LookupFileEntity("foo_Util.h");
			MethodType[] funcs = fileEnt.GetFunctionDeclarations();
			MethodType funcBigWide = funcs[2];
			Reference refDef = funcBigWide.GetRef();

			Lexer lex = fileEnt.GetLexer();
			Lexeme lexme = lex.GetLexeme(refDef.Line, refDef.Column);
			Assert.AreEqual("BigAndWideMethod", lexme.Text);

			Lexeme lexnext = lexme.Next;
			Assert.AreEqual("(", lexnext.Text);
			Assert.AreEqual(UdbToken.Udb_tokenPunctuation, lexnext.Token);

			lexnext = lexnext.Next;
			Assert.AreEqual(" ", lexnext.Text);
			Assert.AreEqual(UdbToken.Udb_tokenWhitespace, lexnext.Token);

			lexnext = lexnext.Next;
			Assert.AreEqual("char", lexnext.Text);
			Assert.AreEqual(UdbToken.Udb_tokenKeyword, lexnext.Token);

			lexnext = lexnext.Next;
			Assert.AreEqual("*", lexnext.Text);
			Assert.AreEqual(UdbToken.Udb_tokenOperator, lexnext.Token);
		}
		[TestMethod]
		public void Lexer_Test_Ref()
		{
			FileEntity fileEnt = Database.LookupFileEntity("foo_Util.h");
			MethodType[] funcs = fileEnt.GetFunctionDeclarations();
			MethodType funcBigWide = funcs[2];
			Reference refDef = funcBigWide.GetRef();

			Lexer lex = fileEnt.GetLexer();
			Lexeme lexme = lex.GetLexeme(refDef.Line, refDef.Column);
			Assert.AreEqual("BigAndWideMethod", lexme.Text);

			Reference lexref = lexme.GetReference();
		}
	}
}
